<template>
    <Window :title="`${(scenetree && scenetree.name) ? scenetree.name : ''}-编辑器`" :show="props.isShow"
        @cancel="changeCancel" @ok="changeOk" :width="800" :height="400">
        <div class="set_style">
            <div class="set_style_list">
                <div class="style_list">
                    <div v-for="(item, index) in styleList" class="set_style_list_lilist">
                        <div class="set_imgposition" :class="{ 'set_checkedactive': checkedactive === index }"
                            @click="changeStyle(item, index)" @contextmenu.prevent.stop="Message.warning('默认样式禁止修改')">
                            <img :src="item.thumbnail" alt="">
                            <span
                                :style="{ right: `${((index + 1) % 4 === 0) ? 0 : 'unset'}`, left: `${((index + 1) % 4 === 0) ? 'unset' : 0}` }"
                                v-show="iconIsShow == index ? true : false">{{ item.name }}</span>
                        </div>
                        <div class="setStyle_onlineimageName" @mouseenter="iconIsShow = index"
                            @mouseleave="iconIsShow = null">
                            {{ item.name }}
                        </div>
                    </div>
                    <div v-for="(item, index) in localStorageStyle" class="set_style_list_lilist">
                        <div class="set_imgposition" :class="{ 'set_checkedactive': checkedactive === index + 5 }"
                            @click="changeStyle(item, index + 5)"
                            @contextmenu.prevent.stop="contexMenuEvent(item, index)">
                            <img :src="item.thumbnail" alt="">
                            <span
                                :style="{ right: `${((index + 6) % 4 === 0) ? 0 : 'unset'}`, left: `${((index + 6) % 4 === 0) ? 'unset' : 0}` }"
                                v-show="iconIsShow == index + 5 ? true : false">{{ item.name }}</span>
                        </div>
                        <div class="setStyle_onlineimageName" @mouseenter="iconIsShow = index + 5"
                            @mouseleave="iconIsShow = null" v-if="inputIndex !== index">
                            {{ item.name }}
                        </div>
                        <input class="model_content_right_input" type="text" :id="`${inputIndex}myInput`"
                            v-model="inputValue" v-else @blur="changeName(item, index)"
                            @keydown.enter="changeName(item, index)" :key="index" ref="myInput">
                    </div>
                </div>
                <div class="style_button">
                    <button @click="saveStyle">另存为新样式</button>
                </div>
            </div>
            <div class="set_style_edit">
                <iframe :src="iframeSrc" frameborder="0" @load="loadIframe" ref="mainIframe"
                    style="width:100%;  height:calc(100% - 10px);cursor: not-allowed"></iframe>
            </div>
        </div>

    </Window>
    <ContextMenuCom :baseItems="menuContent"></ContextMenuCom>

</template>

<script setup lang="ts">
import { Message, messageBox } from "earthsdk-ui";
import { inject, ref, onMounted, watch } from "vue";
import { SceneObject } from "xbsj-xe2/dist-node/xe2-utils";
import Window from "../../../components/commom/Window.vue";
import { XbsjEarthUi } from "../../../scripts/xbsjEarthUi";
import ContextMenuCom from '../../../components/commom/ContextMenuCom.vue';
import { SceneTreeItem } from "xbsj-xe2/dist-node/xe2";
import { ES3DTileset } from "esobjs-xe2-plugin/dist-node/esobjs-xe2-plugin-main";


const props = withDefaults(defineProps<{
    isShow: boolean,
    setStyleTreeItem: SceneTreeItem | undefined,
}>(), {});
const { setStyleTreeItem } = props
const emits = defineEmits(["changeShow"]);
type menuContentType = {
    text: string;
    keys: string;
    func: () => void;
} | {
    type: "divider",
}
const xbsjEarthUi = inject('xbsjEarthUi') as XbsjEarthUi
const mainIframe = ref<HTMLIFrameElement>();
const styleList = ref([
    {
        name: "默认样式",
        code: '{}',
        thumbnail: "",

    },
    {
        name: "纯色",
        code: '{ "color": "vec4(1,0,0,1)" }',
        thumbnail: "",

    },
    {
        name: "半透明",
        code: '{ "color": "vec4(1,1,1,0.5)" }',
        thumbnail: "",

    },
    {
        name: "分类全透12345",
        code: '{ "color": "vec4(0,0,1,0.01)" }',
        thumbnail: "",

    },
    {
        name: "分类浅色",
        code: '{ "color": "vec4(0,0,1,0.1)}" }',
        thumbnail: "",

    }
])

const menuContent = ref<Array<menuContentType>>([])
const inputIndex = ref()
const contextmenuItem = ref()
const changeStyle = async (item: any, index: any) => {
    checkedactive.value = index
    await setJson(item.code)
}
const inputValue = ref()
//失去焦点,按键enter
const changeName = (item: any, index: number) => {
    const modelStyle = window.localStorage.getItem('modelStyle')
    if (modelStyle) {
        const a = JSON.parse(modelStyle)
        a[index].name = inputValue.value
        window.localStorage.setItem('modelStyle', JSON.stringify(a))
        localStorageStyle.value = a
    }
    inputIndex.value = null
}
const contexMenuEvent = (item: any, index: number) => {//元素右键
    contextmenuItem.value = item
    if (!item) return
    const baseItems: Array<menuContentType> = [
        {
            text: "重命名",
            keys: "",
            func: () => {
                inputIndex.value = index
                inputValue.value = item.name
                setTimeout(() => {
                    const a = document.getElementById(`${index}myInput`)
                    if(a){
                        a.focus()
                    }
                }, 50)
            },
        },
        {
            text: "更新缩略图",
            keys: "",
            func: () => {
                messageBox({ text: '确认更新缩略图吗？' })
                    .then(() => {
                        updateConfirm(index)
                    })
                    .catch((err) => {
                    })
            },
        },
        {
            text: "删除",
            keys: "",
            func: () => {
                messageBox({ text: '确认删除？' })
                    .then(() => {
                        deleteConfirm(index)
                    })
                    .catch((err) => {
                    })
            },
        }
    ];
    menuContent.value = baseItems
}
const checkedactive = ref()
const localStorageStyle = ref()
const iconIsShow = ref()
const changeCancel = () => {
    emits("changeShow", false);
}
const scenetree = ref()
watch(() => props.setStyleTreeItem, () => {
    scenetree.value = props.setStyleTreeItem
    checkedactive.value = -2

}, { immediate: true })
const changeOk = async () => {
    try {
        const str = await getJson()
        const json = JSON.parse(str);
        if (scenetree.value && scenetree.value.sceneObject) {
            const sceneObject = scenetree.value.sceneObject as ES3DTileset
            sceneObject.czmStyleJson = json
            checkedactive.value = -2
            emits("changeShow", false);
        }

    } catch (error) {
        console.log('JSON格式错误!!!', error);
        if (error === undefined) {
            Message.error('样式未定义');
        } else {
            Message.error(`JSON格式错误！ error: ${error}`);
        }
        return
    }
}
//另存为新样式
const saveStyle = async () => {
    try {
        const str = await getJson()
        const json = JSON.parse(str);
        const viewer = xbsjEarthUi.activeViewer
        if (!viewer) return
        viewer.capture().then(res => {
            if (res) {
                const parms = {
                    name: '新建样式',
                    code: str,
                    thumbnail: res
                }
                const modelStyle = window.localStorage.getItem('modelStyle')
                if (modelStyle) {
                    const a = JSON.parse(modelStyle)
                    a.push(parms)
                    window.localStorage.setItem('modelStyle', JSON.stringify(a))
                } else {
                    window.localStorage.setItem('modelStyle', JSON.stringify([parms]))
                }
                Message.success('另存样式成功')
                updateList()
            }
        }).catch(error => {
            console.log(error);
            Message.error(`另存样式成功!error:${error}`)
        })

    } catch (error) {
        console.log('JSON格式错误!!!', error);
        if (error === undefined) {
            Message.error('请输入内容之后在保存');
        } else {
            Message.error(`JSON格式错误！ error: ${error}`);
        }
        return
    }

}
const updateList = () => {
    const modelStyle = window.localStorage.getItem('modelStyle')
    if (modelStyle) {
        const a = JSON.parse(modelStyle)
        localStorageStyle.value = a
    }
}
onMounted(() => {
    updateList()

})
//更新缩略图
const updateConfirm = (index: number) => {
    const viewer = xbsjEarthUi.activeViewer
    if (!viewer) return
    viewer.capture().then(res => {
        if (res) {
            const modelStyle = window.localStorage.getItem('modelStyle')
            if (modelStyle) {
                const a = JSON.parse(modelStyle)
                a[index].thumbnail = res
                window.localStorage.setItem('modelStyle', JSON.stringify(a))
                localStorageStyle.value = a
            }
            inputIndex.value = null
        }
    }).catch(error => {
        console.log(error);

    })
}
//删除
const deleteConfirm = (index: number) => {
    const modelStyle = window.localStorage.getItem('modelStyle')
    if (modelStyle) {
        let a = JSON.parse(modelStyle)
        a.splice(index, 1)
        window.localStorage.setItem('modelStyle', JSON.stringify(a))
        localStorageStyle.value = a
    }
    inputIndex.value = null
}
const getAssetsDir = () => {
    return SceneObject.context.getEnv(`vue-xe2-plugin-assets-dir`);
}
function setJson(value: string) {
    return new Promise<void>((resolve, reject) => {
        if (!mainIframe.value || !mainIframe.value.contentWindow) {
            return;
        }
        const setKey = getUuid()
        mainIframe.value.contentWindow.postMessage({ type: 'setJson', id: setKey, value })
        const time = setTimeout(() => {
            removeEventListener('message', messageSetEventWatch, false);
            reject();
        }, 10000);

        const messageSetEventWatch = (messageEvent: MessageEvent<{ type: string, id: string, status: string } | undefined>) => {
            var data = messageEvent.data;
            if (!data || (data.type && data.type !== 'setJsonReturn') || (data.id && data.id !== setKey)) {
                return;
            }
            removeEventListener('message', messageSetEventWatch, false);
            clearTimeout(time)
            if (data.status === 'ok') {
                resolve();
            } else {
                reject();
            }
        }
        addEventListener('message', messageSetEventWatch, false);
    })

}
const loadIframe = async () => {
    await setJson('{}')
}
const iframeSrc = getAssetsDir() + '/monaco-editor/json-editor.html';

function getUuid() {
    var d = new Date().getTime();
    if (window.performance && typeof window.performance.now === "function") {
        d += performance.now();
    }
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
}
function getJson() {
    return new Promise<string>((resolve, reject) => {
        if (!mainIframe.value || !mainIframe.value.contentWindow) {
            return;
        }
        const getKey = getUuid()
        mainIframe.value.contentWindow.postMessage({ type: 'getJson', id: getKey })
        const time = setTimeout(() => {
            removeEventListener('message', messageGetEventWatch, false);
            reject();
        }, 10000);

        const messageGetEventWatch = (messageEvent: MessageEvent<{ type: string, id: string, status: string, value: string | undefined } | undefined>) => {
            var data = messageEvent.data;
            if (!data || (data.type && data.type !== 'getJsonReturn') || (data.id && data.id !== getKey)) {
                return;
            }
            removeEventListener('message', messageGetEventWatch, false);
            clearTimeout(time)
            if (data.status === 'ok' && data.value) {
                resolve(data.value);
            } else {
                reject();
            }
        }
        addEventListener('message', messageGetEventWatch, false);
    })

}
</script>
<style scoped>
.set_style {
    width: 100%;
    height: 100%;
    display: flex;
}

.set_style_list {
    width: 250px;
    height: 100%;
    padding: 10px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
}

.set_style_list>.style_list {
    width: 100%;
    height: auto;
    display: flex;
    justify-content: flex-start;
    align-items: flex-start;
    flex-wrap: wrap;
    overflow: auto;
    max-height: 85%;
    overflow-x: hidden;
}


.set_style_list>.style_button {
    width: 100%;
    height: 15%;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.style_button>a,
.style_button>button {
    height: 32px;
    background: rgba(28, 28, 29, 0.6);
    border-radius: 4px;
    border: 1px solid #3b3c40;
    cursor: pointer;
    color: rgba(230, 230, 230, 1);
    padding: 0 10px;
    text-decoration: none;
    font-size: 12px;
    line-height: 32px;
}

.style_button>a:hover {
    border: 1px solid rgba(44, 104, 247, 1);
}

.style_button>button:hover {
    border: 1px solid rgba(44, 104, 247, 1);
}

.set_style_list_lilist {
    width: 50px;
    height: 80px;
    margin-right: 6px;
    border-radius: 5px;
    position: relative;
}

.set_imgposition {
    border-radius: 5px;
    width: 50px;
    height: 50px;
    cursor: pointer;
    border: 2px solid rgba(37, 38, 42, 0.9);
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
}

.set_imgposition>img {
    width: 100%;
    height: 100%;
    border-radius: 3px;
}

.set_style_edit {
    flex: 1;
    height: 100%;
}

.setStyle_onlineimageName {
    display: inline-block;
    width: 46px;
    text-align: center;
    margin-left: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #fff;
    cursor: pointer;
    font-size: 14px;
}

.set_imgposition>span {
    position: absolute;
    bottom: 23px;
    white-space: nowrap;
    padding: 2px;
    z-index: 10000;
    border-radius: 2px;
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    font-size: 12px;
    /* width: 46px; */
}

.set_imgposition:hover {
    border: 2px solid rgba(44, 104, 247, 1);
}

.set_checkedactive {
    border: 2px solid rgba(44, 104, 247, 1);
}

.model_content_right_input {
    width: 50px;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    display: block;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    border: none;
    outline: none;
}
</style>